package com.fancy.music.controller;

import com.fancy.common.dto.PageResult;
import com.fancy.common.dto.SongBasicInfo;
import com.fancy.common.dto.response.Result;
import com.fancy.music.dto.GlobalSearchResultDTO;
import com.fancy.music.dto.SongDetailDTO;
import com.fancy.music.entity.Song;
import com.fancy.music.service.SongService;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.util.List;

@Api(tags = "歌曲管理")
@RestController
@RequestMapping("/api/v1/songs")
@RequiredArgsConstructor
public class SongController {

    private final SongService songService;

    @ApiOperation(value = "歌曲搜索", notes = "根据关键词、风格、语言等条件搜索歌曲")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "keyword", value = "搜索关键词", paramType = "query", dataType = "string", example = "周杰伦"),
        @ApiImplicitParam(name = "genre", value = "音乐风格", paramType = "query", dataType = "string", example = "流行"),
        @ApiImplicitParam(name = "language", value = "语言", paramType = "query", dataType = "string", example = "中文"),
        @ApiImplicitParam(name = "isVip", value = "是否VIP歌曲(0-否,1-是)", paramType = "query", dataType = "int", example = "0"),
        @ApiImplicitParam(name = "page", value = "页码", paramType = "query", dataType = "int", example = "1"),
        @ApiImplicitParam(name = "size", value = "每页大小", paramType = "query", dataType = "int", example = "20")
    })
    @ApiResponses({
        @ApiResponse(code = 200, message = "搜索成功"),
        @ApiResponse(code = 400, message = "参数错误"),
        @ApiResponse(code = 500, message = "服务器内部错误")
    })
    @GetMapping("/search")
    public Result<PageResult<Song>> searchSongs(
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) String genre,
            @RequestParam(required = false) String language,
            @RequestParam(required = false) Integer isVip,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "20") int size) {
        PageResult<Song> result = songService.searchSongs(keyword, genre, language, isVip, page, size);
        return Result.success(result);
    }

    @ApiOperation(value = "获取歌曲详情", notes = "根据歌曲ID获取歌曲的详细信息")
    @ApiImplicitParam(name = "songId", value = "歌曲ID", required = true, paramType = "path", dataType = "long", example = "1")
    @ApiResponses({
        @ApiResponse(code = 200, message = "获取成功"),
        @ApiResponse(code = 404, message = "歌曲不存在"),
        @ApiResponse(code = 500, message = "服务器内部错误")
    })
    @GetMapping("/{songId}")
    public Result<SongDetailDTO> getSongDetail(@PathVariable Long songId) {
        SongDetailDTO songDetail = songService.getSongDetailWithInfo(songId);
        if (songDetail != null) {
            return Result.success(songDetail);
        } else {
            return Result.fail("歌曲不存在");
        }
    }

    @ApiOperation(value = "播放歌曲", notes = "播放指定歌曲并返回播放链接")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "songId", value = "歌曲ID", required = true, paramType = "path", dataType = "long", example = "1"),
        @ApiImplicitParam(name = "userId", value = "用户ID", required = true, paramType = "query", dataType = "long", example = "1001")
    })
    @ApiResponses({
        @ApiResponse(code = 200, message = "播放成功"),
        @ApiResponse(code = 403, message = "无播放权限"),
        @ApiResponse(code = 404, message = "歌曲不存在")
    })
    @PostMapping("/{songId}/play")
    public Result<String> playSong(@PathVariable Long songId, @RequestParam Long userId) {
        try {
            String playUrl = songService.playSong(songId, userId);
            return Result.success(playUrl);
        } catch (Exception e) {
            return Result.fail(e.getMessage());
        }
    }

    @ApiOperation(value = "获取歌词", notes = "获取指定歌曲的歌词内容")
    @ApiImplicitParam(name = "songId", value = "歌曲ID", required = true, paramType = "path", dataType = "long", example = "1")
    @GetMapping("/{songId}/lyrics")
    public Result<String> getSongLyrics(@PathVariable Long songId) {
        Song song = songService.getSongDetail(songId);
        if (song != null) {
            return Result.success(song.getLyricUrl());
        } else {
            return Result.fail("歌曲不存在");
        }
    }

    @ApiOperation(value = "获取热门歌曲", notes = "获取热门歌曲列表")
    @ApiImplicitParam(name = "limit", value = "返回数量限制", paramType = "query", dataType = "int", example = "10")
    @GetMapping("/hot")
    public Result<List<SongDetailDTO>> getHotSongs(@RequestParam(defaultValue = "10") Integer limit) {
        List<SongDetailDTO> songs = songService.getHotSongsWithDetails(limit);
        return Result.success(songs);
    }

    @ApiOperation(value = "获取新歌", notes = "获取最新发布的歌曲列表")
    @ApiImplicitParam(name = "limit", value = "返回数量限制", paramType = "query", dataType = "int", example = "10")
    @GetMapping("/new")
    public Result<List<SongDetailDTO>> getNewSongs(@RequestParam(defaultValue = "10") Integer limit) {
        List<SongDetailDTO> songs = songService.getNewSongsWithDetails(limit);
        return Result.success(songs);
    }

    @ApiOperation(value = "获取推荐歌曲", notes = "根据用户喜好获取个性化推荐歌曲")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "userId", value = "用户ID", required = true, paramType = "query", dataType = "long", example = "1001"),
        @ApiImplicitParam(name = "limit", value = "返回数量限制", paramType = "query", dataType = "int", example = "10")
    })
    @GetMapping("/recommendations")
    public Result<List<SongDetailDTO>> getRecommendations(
            @RequestParam Long userId,
            @RequestParam(defaultValue = "10") Integer limit) {
        List<SongDetailDTO> songs = songService.getRecommendedSongsWithDetails(userId, limit);
        return Result.success(songs);
    }

    @ApiOperation(value = "根据歌手获取歌曲", notes = "获取指定歌手的所有歌曲")
    @ApiImplicitParam(name = "artistId", value = "歌手ID", required = true, paramType = "path", dataType = "long", example = "1")
    @GetMapping("/artist/{artistId}")
    public Result<List<SongDetailDTO>> getSongsByArtist(@PathVariable Long artistId) {
        List<SongDetailDTO> songs = songService.getSongsByArtistIdWithDetails(artistId);
        return Result.success(songs);
    }

    @ApiOperation(value = "根据专辑获取歌曲", notes = "获取指定专辑的所有歌曲")
    @ApiImplicitParam(name = "albumId", value = "专辑ID", required = true, paramType = "path", dataType = "long", example = "1")
    @GetMapping("/album/{albumId}")
    public Result<List<SongDetailDTO>> getSongsByAlbum(@PathVariable Long albumId) {
        List<SongDetailDTO> songs = songService.getSongsByAlbumIdWithDetails(albumId);
        return Result.success(songs);
    }

    // 内部接口，不显示在API文档中
    @ApiIgnore
    @GetMapping("/internal/{songId}")
    public Result<SongBasicInfo> getSongBasicInfo(@PathVariable Long songId) {
        SongBasicInfo info = songService.getSongBasicInfo(songId);
        return Result.success(info);
    }

    @ApiIgnore
    @PostMapping("/internal/batch")
    public Result<List<SongBasicInfo>> getSongBasicInfoBatch(@RequestBody List<Long> songIds) {
        List<SongBasicInfo> infos = songService.getSongBasicInfoBatch(songIds);
        return Result.success(infos);
    }

    @ApiIgnore
    @GetMapping("/internal/{songId}/vip-status")
    public Result<Boolean> isVipSong(@PathVariable Long songId) {
        boolean isVip = songService.isVipSong(songId);
        return Result.success(isVip);
    }

    @ApiOperation(value = "获取所有歌曲音乐风格", notes = "获取系统中所有歌曲的音乐风格标签")
    @GetMapping("/genres")
    public Result<List<String>> getAllSongGenres() {
        List<String> genres = songService.getAllSongGenres();
        return Result.success(genres);
    }

    @ApiOperation(value = "根据音乐风格获取歌曲", notes = "根据音乐风格获取匹配的歌曲列表（支持部分匹配）")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "genre", value = "音乐风格", required = true, paramType = "query", dataType = "string", example = "华语流行"),
        @ApiImplicitParam(name = "limit", value = "返回数量限制", paramType = "query", dataType = "int", example = "10")
    })
    @GetMapping("/by-genre-match")
    public Result<List<SongDetailDTO>> getSongsByGenreMatch(
            @RequestParam String genre,
            @RequestParam(defaultValue = "10") Integer limit) {
        List<SongDetailDTO> songs = songService.getSongsByGenreMatchWithDetails(genre, limit);
        return Result.success(songs);
    }

    @ApiOperation(value = "全局搜索", notes = "全局搜索歌曲、歌手、专辑，支持模糊匹配")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "keyword", value = "搜索关键词", required = true, paramType = "query", dataType = "string", example = "周杰伦"),
        @ApiImplicitParam(name = "limit", value = "每种类型返回数量限制", paramType = "query", dataType = "int", example = "10")
    })
    @ApiResponses({
        @ApiResponse(code = 200, message = "搜索成功"),
        @ApiResponse(code = 400, message = "参数错误"),
        @ApiResponse(code = 500, message = "服务器内部错误")
    })
    @GetMapping("/global-search")
    public Result<GlobalSearchResultDTO> globalSearch(
            @RequestParam String keyword,
            @RequestParam(defaultValue = "10") Integer limit) {
        GlobalSearchResultDTO result = songService.globalSearch(keyword, limit);
        return Result.success(result);
    }
}
